#ifndef GAMEMANAGER_HEADER
#define GAMEMANAGER_HEADER

#include <string>
#include "OblivionDisplay.h"
#include "OblivionPhysics.h"

#include "PhysicsManager.h"
#include "Globals.h"
#include "EventHandler.h"
#include "Spawner.h"
#include <glm/glm.hpp>
#include <glm/ext.hpp>
//#include "PhysicsManager.h"
//#include "PhysicsFactory.h"

struct Level {
	std::string mName; //Name of level
	glm::vec2 mStartPoint; //Starting position of the player
	
};

class GameManager {
public:

	Spawner mSpawner;
	
	Texture * testTex;

	GameManager();
	~GameManager();

	void SetCurrLevel (Level * inLev);
	
	//Main game entry loop
	void MainLoop();
	
	bool Init();
	
	bool InitGraphics();
	
	bool InitPhysics();
	
	bool InitGame();

	void InitPlayer(PlayerGameEntity * inEntity);
	
	bool InitLevel( Level * lvlPtr);
	
	void Update();
	
	void Display();
	
	Displayer * GetDisplayer();
	
	//Polls event handler for the input events recieved.
	void ProcessInputEvents();

	//For events
	//Polls user input.  Will spawn events.
	void PollUserInput();

	//Registers an event to be handled.
	void RegisterEvent( const EventRec & inRec );
	
	bool IsTimeToUpdate();
	
	bool IsTimeToDisplay();
	
	int Run();

	static void GLFWCALL GameKeyboardCallback(int uniKey, int state);
	static void GLFWCALL GameMouseMoveCallback(int x, int y);
	static void GLFWCALL GameMouseButtonCallback(int butt, int state);

	void InitInputCallbacks();

	//TO BE PRIVATE

	Level * mCurrLevel;
	EventHandler mEventHandler;

	//Some states
	InputStateRec mInputState;
	
	PhysicsManager * mPhysicsManager;
	
	Displayer * mDisplayManager;
	
	bool mIsRunning;
	
	bool mIsGraphicsInit;
	unsigned int mWindowW, mWindowH;
	bool mIsPhysicsInit;
	
	PlayerGameEntity * mPlayer; //The entity corresponding to the player.

	std::vector<GameEntity *> mEntityList;
	
	double mUpdateTimeStep;
	
	bool mEditMode;
	
	std::vector<GameEntity *> mObjs; //All objects in the scene that are not the player
	
	static GameManager * mActiveManager; //For callbacks

	MouseInfoRec mCurrMouseInfo;
};

#endif